﻿using System;
using System.ComponentModel;

namespace LeakView.common
{
#pragma warning disable IDE1006 // 命名样式
    public interface Any
#pragma warning restore IDE1006 // 命名样式
    {
        /// <summary>
        /// 获取具体值，如果失败，则用默认值替代
        /// </summary>
        T GetOrDefault<T>(T def);

        /// <summary>
        /// 获取具体值，如果失败，则抛出以尝
        /// </summary>
        T Get<T>();
    }

    public class Anys<V> : Any
    {
        public static Any At(V value)
        {
            return new Anys<V>(value);
        }

        private V value;

        private Anys(V value)
        {
            this.value = value;
        }

        public T GetOrDefault<T>(T def)
        {
            try
            {
                return Get<T>();
            }
            catch
            {
                return def;
            }
        }

        public T Get<T>()
        {
            if (value == null)
            {
                throw new InvalidCastException();
            }

            try
            {

                Type destinationType = typeof(T);

                TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
                if (converter.CanConvertFrom(value.GetType()))
                {
                    return (T)converter.ConvertFrom(null, null, value);
                }

                converter = TypeDescriptor.GetConverter(value.GetType());
                if (converter.CanConvertTo(destinationType))
                {
                    return (T)converter.ConvertTo(null, null, value, destinationType);
                }

                throw new InvalidCastException();
            }
            catch
            {
                throw new InvalidCastException();
            }
        }
    }
    

}
